#include<iostream>
#include<queue>
#include<vector>
#include<algorithm>
 const int maxn=0x3f3f3f3f;
using namespace std;
struct point{
    int id;
    int dist=maxn;
    int qg;
};
struct Comparepoint{
    bool operator()(const point &t1,const point &t2){
       if(t1.dist==t2.dist){
         return t1.qg>t2.qg;
       }
       else return t1.dist>t2.dist;
    }
};
struct sided{
    int md;
    int v;
    int qg;
};
point side1[20005];
vector<sided>side[20002];
int dist[20002][2];
int ans1[20002];
int ans2[20002];
void dj(int n,int s){
    priority_queue<point,vector<point>,Comparepoint>q;
    for(int i=1;i<=n;i++){
        side1[i].dist=maxn;
        side1[i].id=i;
        side1[i].qg=0;
        dist[i][0]=maxn;
        dist[i][1]=maxn;
    }
    side1[s].dist=0;
       dist[s][0]=0;
        dist[s][1]=0;
    q.push(side1[s]);
    while(!q.empty()){
        point f;
        f=q.top();
        q.pop();
        int now=f.dist;
        for(int i=0;i<side[f.id].size();i++){
            if(side[f.id][i].qg){
               if((dist[f.id][0]+side[f.id][i].v)<dist[side[f.id][i].md][1]){
                dist[side[f.id][i].md][1]=dist[f.id][0]+side[f.id][i].v;
               point a;
               a.dist=dist[f.id][0]+side[f.id][i].v;
               a.id=side[f.id][i].md;
               a.qg=f.id;
               side1[side[f.id][i].md].qg=a.qg;
               q.push(a);
               }
               if((dist[f.id][0]+side[f.id][i].v)==dist[side[f.id][i].md][1]){
                
               if(f.id<side1[side[f.id][i].md].qg)
              {
                point a;
                a.dist=dist[f.id][0]+side[f.id][i].v;
               a.id=side[f.id][i].md;
               a.qg=f.id;
               side1[side[f.id][i].md].qg=f.id;
               q.push(a);
              }
               }
            }
            if(!side[f.id][i].qg){
                if(side[f.id][i].v+dist[f.id][1]<dist[side[f.id][i].md][1]){
                    dist[side[f.id][i].md][1]=side[f.id][i].v+dist[f.id][1];
                    point a;
                    a.dist=side[f.id][i].v+dist[f.id][1];
                    a.id=side[f.id][i].md;
                    a.qg=f.qg;
                    side1[side[f.id][i].md].qg=f.qg;
                    q.push(a);
                }
                if(side[f.id][i].v+dist[f.id][0]<dist[side[f.id][i].md][0]){
                    dist[side[f.id][i].md][0]=side[f.id][i].v+dist[f.id][0];
                    point a;
                    a.dist=side[f.id][i].v+dist[f.id][0];
                    a.id=side[f.id][i].md;
                    a.qg=0;
                    q.push(a);
                }
            }
        }
    }
}
int main(){
    int n,s,t;
    int nans=0;
        int m;
    while(cin>>n>>s>>t){
        nans++;
        cin>>m;
        for(int i=1;i<=n;i++){
            side[i].clear();
        }
        for(int i=1;i<=m;i++){
            int x,y,z;
            cin>>x>>y>>z;
            sided a;
            a.md=y;
            a.v=z;
            a.qg=0;
            side[x].push_back(a);
             sided b;
            b.md=x;
            b.v=z;
            b.qg=0;
            side[y].push_back(b);
        }
        int k;
        cin>>k;
        int ansi=side1[t].dist;
        int bh=maxn;
        for(int i=1;i<=k;i++){
            int x,y,z;
            cin>>x>>y>>z;
            sided a;
            a.md=y;
            a.v=z;
            a.qg=x;
            side[x].push_back(a);
             sided b;
            b.md=x;
            b.v=z;
            b.qg=y;
            side[y].push_back(b);
            }
            dj(n,s);
            if(dist[t][1]>=dist[t][0])ans1[nans]=dist[t][0];
            if(dist[t][0]>dist[t][1]){
                ans1[nans]=dist[t][1];
                ans2[nans]=side1[t].qg;
            }
        }
    for(int i=1;i<=nans;i++){
        cout<<ans1[i]<<endl;
        if(ans2[i]!=0)cout<<ans2[i]<<endl;
        else cout<<"no metro"<<endl;
    }
    return 0;
}
//pair<int,int>.first第一个。
//greater<pair<int,int>> 根据第一个排序。优先队列快速写